from django.core.files.storage import Storage
from django.conf import settings
from django.utils import timezone
from fdfs_client.client import Fdfs_client
from rest_framework import serializers

class FdfsStorage(Storage):

    def _open(self, name, mode='rb'):
        """
        打开django服务器的一个本地文件——把浏览器给的图片保存在django本地,
        由于我们需要把图片上传到fdfs，所以该函数无用
        :param name:
        :param mode:
        :return:
        """
        return None # 无需保存本地


    def _save(self, name, content, max_length=None):
       """
       编写文件保存业务逻辑(上传fdfs)
       :param name: 文件名
       :param content: 经过类型校验之后得到的文件对象
       :param max_length: 最大文件长度
       :return: 返回的数据，就是存储在mysql中数据(把fdfs返回的文件唯一标示返回)
       """
       # 1、构建fdfs客户端对象
       c = Fdfs_client('meiduo_mall/client.conf')
       # 2、调用函数完成上传
       res = c.upload_by_buffer(content.read())
       # 3、判断是否上传成功
       if res['Status'] != 'Upload successed.':
           # 上传失败，就相当于校验失败
           raise serializers.ValidationError("图片上传失败！")

       # 4、返回文件标示（存储在mysql中的文件字段image的值）
       return res['Remote file_id']


    def exists(self, name):
        """
        判断上传的文件是否已经存在(针对django本地保存而言)
        :param name:
        :return: True标示已经存在，False标示不存在
        """
        # 无需判断是否存在，一律当作本地未保存，直接调用_save方法实现上传
        # ps：我们重复上传到fdfs文件，fdfs服务器会自行判断是否已经保存，并且不会重复保存
        return False


    def url(self, name):
        return settings.FDFS_URL + name




# validated_data = {
# 	“image”:  <图片文件对象>
# }
# SKUImage.objects.create(
# 	image = <图片文件对象>
# )
# 如果我们在新建SKUImage对象的时候
# 给image赋值为一个图片对象，那么会
# 调用自定义的图片存储后端完成保存图片
# ---->
# 不再序列化器里重写 validate实现上传，
# 就需要重写后端存储来完成图片上传